﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.IO;
using Cs2102BookingSystem.Models;

namespace Cs2102BookingSystem.Controllers
{
    public class AdminCreateController : Controller
    {
        private BookingEntities _db = new BookingEntities();
        public ActionResult Index()
        {
            return View();
        }
        [HttpPost]
        public ActionResult Index(FormCollection form)
        {
            try
            {
                ActionResult result;
                var radioButtonResult = form["radioButtonCreateSelection"];
                switch (radioButtonResult)
                {
                    case "_hotel":
                        result = RedirectToAction("CreateHotel");
                        break;
                    case "_facility":
                        result = RedirectToAction("CreateFacility");
                        break;
                    case "_room":
                        result = RedirectToAction("CreateRoom");
                        break;
                    case "_client":
                        result = RedirectToAction("CreateClient");
                        break;
                    case "_booking":
                        result = RedirectToAction("CreateBooking");
                        break;
                    default:
                        result = RedirectToAction("Index");
                        break;
                }
                return result;
            }
            catch
            {
                return View();
            }
        }

        public ActionResult CreateHotel()
        {
            return View();
        }
        [HttpPost]
        public ActionResult CreateHotel(HOTEL newHotel, HttpPostedFileBase file)
        {
            string filename_with_path = "";
            bool file_uploaded = false;
            try
            {
                newHotel.HOTEL_NAME = toTitleCase(newHotel.HOTEL_NAME);
                newHotel.COUNTRY = toTitleCase(newHotel.COUNTRY);
                newHotel.BRANCHNAME = toTitleCase(newHotel.BRANCHNAME);
                newHotel.DISTRICT = toTitleCase(newHotel.DISTRICT);
                newHotel.ADDRESS = toTitleCase(newHotel.ADDRESS);
                //error checking
                int error_state = 0;
                if (string.IsNullOrWhiteSpace(newHotel.HOTEL_NAME))
                {
                    error_state++;
                    ViewData["NAME_ERROR"] = "Name is a required field";
                }
                if (string.IsNullOrWhiteSpace(newHotel.COUNTRY))
                {
                    error_state++;
                    ViewData["COUNTRY_ERROR"] = "Country is a required field";
                }
                if (string.IsNullOrWhiteSpace(newHotel.BRANCHNAME))
                {
                    error_state++;
                    ViewData["BRANCHNAME_ERROR"] = "Branch Name is a required field";
                }
                if (string.IsNullOrWhiteSpace(newHotel.DISTRICT))
                {
                    error_state++;
                    ViewData["DISTRICT_ERROR"] = "District is a required field";
                }
                if (string.IsNullOrWhiteSpace(newHotel.ADDRESS))
                {
                    error_state++;
                    ViewData["ADDRESS_ERROR"] = "Address is a required field";
                }
                string input = Request.Form.Get("CONTACT");
                if (string.IsNullOrWhiteSpace(input))
                {
                    error_state++;
                    ViewData["CONTACT_ERROR"] = "Contact is a required field";
                }
                else if (newHotel.CONTACT == 0)
                {
                    error_state++;
                    ViewData["CONTACT_ERROR"] = "Invalid Contact!";
                }
                if (newHotel.HOTEL_NAME != null && newHotel.COUNTRY != null && newHotel.BRANCHNAME != null)
                {
                    var hotels = from Hotel in _db.HOTEL
                                 where Hotel.HOTEL_NAME == newHotel.HOTEL_NAME &&
                                 Hotel.COUNTRY == newHotel.COUNTRY &&
                                 Hotel.BRANCHNAME == newHotel.BRANCHNAME
                                 select Hotel;
                    if (hotels.Count() > 0)
                    {
                        error_state++;
                        ViewData["ERROR"] = "A Hotel with the same Name, Country and Branch Name already exists!";
                    }
                }
                error_state += checkLengthAndPopulateError(ViewData, newHotel.HOTEL_NAME, 80, "NAME_ERROR", "Name");
                error_state += checkLengthAndPopulateError(ViewData, newHotel.COUNTRY, 60, "COUNTRY_ERROR", "Country");
                error_state += checkLengthAndPopulateError(ViewData, newHotel.BRANCHNAME, 60, "BRANCHNAME_ERROR", "Branch");
                error_state += checkLengthAndPopulateError(ViewData, newHotel.DESCRIPTION, 512, "DESCRIPTION_ERROR", "Description");
                error_state += checkLengthAndPopulateError(ViewData, newHotel.ADDRESS, 255, "ADDRESS_ERROR", "Address");
                error_state += checkLengthAndPopulateError(ViewData, newHotel.DISTRICT, 60, "DISTRICT_ERROR", "District");
                if (error_state > 0)
                {
                    return View(newHotel);
                }
                if (file != null && file.ContentLength > 0)
                {
                    var fileName = Path.GetFileName(file.FileName);
                    filename_with_path = Path.Combine(Server.MapPath("~/Content"), fileName);

                    var directory = Path.GetDirectoryName(filename_with_path);
                    var filename_without_extension = Path.GetFileNameWithoutExtension(filename_with_path);
                    var extension = Path.GetExtension(filename_with_path);

                    int i = 0;
                    while (System.IO.File.Exists(filename_with_path))
                    {
                        i++;
                        fileName = filename_without_extension + i.ToString() + extension;
                        filename_with_path = Path.Combine(directory, fileName);
                    }

                    file.SaveAs(filename_with_path);
                    file_uploaded = true;

                    var relative_path = "/Content/" + fileName;
                    newHotel.HOTELIMAGE = relative_path;
                }
                _db.AddToHOTEL(newHotel);
                _db.SaveChanges();
                return RedirectToAction("../AdminMain/ViewDetailsHotel", new { hotelName = newHotel.HOTEL_NAME, branchName = newHotel.BRANCHNAME, country = newHotel.COUNTRY });
            }
            catch (System.Web.HttpException e)
            {
                ViewData["ERROR"] = "An error has occurred during uploading of the image!";
                if (file_uploaded && System.IO.File.Exists(filename_with_path))
                {
                    System.IO.File.Delete(filename_with_path);
                }
                return View(newHotel);
            }
            catch
            {
                ViewData["ERROR"] = "An unknown error has occurred! Please try again later.";
                if (file_uploaded && System.IO.File.Exists(filename_with_path))
                {
                    System.IO.File.Delete(filename_with_path);
                }
                return View(newHotel);
            }
        }

        public ActionResult CreateFacility(HOTEL init_hotel = null)
        {

            SelectList hotel_names = getHotelNames(init_hotel.HOTEL_NAME);
            ViewData["hotel_names"] = hotel_names;

            string hotel_name = hotel_names.First().Text;
            if (init_hotel.HOTEL_NAME != null)
            {
                hotel_name = init_hotel.HOTEL_NAME;
            }
            var country_names = getCountryNames(hotel_name, init_hotel.COUNTRY);

            ViewData["country_names"] = country_names;

            string country_name = country_names.First().Text;
            if (init_hotel.COUNTRY != null)
            {
                country_name = init_hotel.COUNTRY;
            }
            var branch_names = getBranchNames(hotel_name, country_name, init_hotel.BRANCHNAME);
            ViewData["branch_names"] = branch_names;
            return View();
        }
        [HttpPost]
        public ActionResult CreateFacility(FACILITIES newFacility, HttpPostedFileBase file)
        {
            string filename_with_path = "";
            bool file_uploaded = false;
            try
            {
                newFacility.FACILITY = toTitleCase(newFacility.FACILITY);
                //error checking
                SelectList hotel_names;
                SelectList branch_names;
                SelectList country_names;
                string ctrlname = Request.Params.Get("__EVENTTARGET");
                bool submit = Request.Form.Get("submit1") != null;
                if (!submit)           //postback not due to submit button
                {
                    hotel_names = getHotelNames(newFacility.H_NAME);
                    ViewData["hotel_names"] = hotel_names;

                    string hotel_name = hotel_names.First().Text;
                    if (newFacility.H_NAME != null)
                    {
                        hotel_name = newFacility.H_NAME;
                    }
                    country_names = getCountryNames(hotel_name);

                    ViewData["country_names"] = country_names;

                    string country_name = country_names.First().Text;

                    foreach (SelectListItem s in country_names)
                    {
                        if (string.Compare(s.Text, newFacility.H_COUNTRY, true) == 0)
                        {
                            country_name = s.Text;
                            break;
                        }
                    }
                    newFacility.H_COUNTRY = country_name;


                    branch_names = getBranchNames(hotel_name, country_name);
                    ViewData["branch_names"] = branch_names;
                    return View(newFacility);
                }
                else                                    //postback due to submit button
                {
                    int error_state = 0;
                    if(string.IsNullOrWhiteSpace(newFacility.FACILITY))
                    {
                        error_state++;
                        ViewData["FACILITY_ERROR"] = "Facility Type is a required field";
                    }
                    if (newFacility.FACILITY != null && newFacility.H_NAME != null && newFacility.H_COUNTRY != null && newFacility.H_BRANCHNAME != null)
                    {
                        var facilities = from Facility in _db.FACILITIES
                                         where Facility.H_NAME == newFacility.H_NAME &&
                                         Facility.H_COUNTRY == newFacility.H_COUNTRY &&
                                         Facility.H_BRANCHNAME == newFacility.H_BRANCHNAME &&
                                         Facility.FACILITY == newFacility.FACILITY
                                         select Facility;
                        if (facilities.Count() > 0)
                        {
                            error_state++;
                            ViewData["ERROR"] = "The Hotel already has that facility! Please change the facility name!";
                        }
                    }
                    error_state += checkLengthAndPopulateError(ViewData, newFacility.FACILITY, 80, "FACILITY_ERROR", "Facility");
                    error_state += checkLengthAndPopulateError(ViewData, newFacility.DESCRIPTION, 512, "DESCRIPTION_ERROR", "Description");
                    if(error_state > 0)
                    {
                        populateHotelListForDropDownList(ViewData, newFacility.H_NAME, newFacility.H_COUNTRY, newFacility.H_BRANCHNAME);
                        return View(newFacility);
                    }

                    if (file != null && file.ContentLength > 0)
                    {
                        var fileName = Path.GetFileName(file.FileName);
                        filename_with_path = Path.Combine(Server.MapPath("~/Content"), fileName);

                        var directory = Path.GetDirectoryName(filename_with_path);
                        var filename_without_extension = Path.GetFileNameWithoutExtension(filename_with_path);
                        var extension = Path.GetExtension(filename_with_path);

                        int i = 0;
                        while (System.IO.File.Exists(filename_with_path))
                        {
                            i++;
                            fileName = filename_without_extension + i.ToString() + extension;
                            filename_with_path = Path.Combine(directory, fileName);
                        }

                        file.SaveAs(filename_with_path);
                        file_uploaded = true;

                        var relative_path = "/Content/" + fileName;
                        newFacility.FACILITYIMAGE = relative_path;
                    }
                    _db.AddToFACILITIES(newFacility);
                    _db.SaveChanges();
                    return RedirectToAction("../AdminMain/ViewDetailsHotel", new { hotelName = newFacility.H_NAME, branchName = newFacility.H_BRANCHNAME, country = newFacility.H_COUNTRY });
                }
            }
            catch (System.Web.HttpException e)
            {
                ViewData["ERROR"] = "An error has occurred during uploading of the image!";
                if (file_uploaded && System.IO.File.Exists(filename_with_path))
                {
                    System.IO.File.Delete(filename_with_path);
                }
                populateHotelListForDropDownList(ViewData, newFacility.H_NAME, newFacility.H_COUNTRY, newFacility.H_BRANCHNAME);
                return View(newFacility);
            }
            catch
            {
                ViewData["ERROR"] = "An unknown error has occurred! Please try again later.";
                if (file_uploaded && System.IO.File.Exists(filename_with_path))
                {
                    System.IO.File.Delete(filename_with_path);
                }
                populateHotelListForDropDownList(ViewData, newFacility.H_NAME, newFacility.H_COUNTRY, newFacility.H_BRANCHNAME);
                return View(newFacility);
            }
        }

        public ActionResult CreateRoom(HOTEL init_hotel = null)
        {
            SelectList hotel_names = getHotelNames(init_hotel.HOTEL_NAME);
            ViewData["hotel_names"] = hotel_names;

            string hotel_name = hotel_names.First().Text;
            if (init_hotel.HOTEL_NAME != null)
            {
                hotel_name = init_hotel.HOTEL_NAME;
            }
            var country_names = getCountryNames(hotel_name, init_hotel.COUNTRY);

            ViewData["country_names"] = country_names;

            string country_name = country_names.First().Text;
            if (init_hotel.COUNTRY != null)
            {
                country_name = init_hotel.COUNTRY;
            }
            var branch_names = getBranchNames(hotel_name, country_name, init_hotel.BRANCHNAME);
            ViewData["branch_names"] = branch_names;
            return View();
        }
        [HttpPost]
        public ActionResult CreateRoom(ROOM newRoom, HttpPostedFileBase file)
        {
            string filename_with_path = "";
            bool file_uploaded = false;
            try
            {
                newRoom.ROOMTYPE = toTitleCase(newRoom.ROOMTYPE);
                newRoom.BEDTYPE = toTitleCase(newRoom.BEDTYPE);
                newRoom.DIRECTION = toTitleCase(newRoom.DIRECTION);

                SelectList hotel_names;
                SelectList branch_names;
                SelectList country_names;
                string ctrlname = Request.Params.Get("__EVENTTARGET");
                bool submit = Request.Form.Get("submit1") != null;
                if (!submit)           //postback not due to submit button
                {
                    hotel_names = getHotelNames(newRoom.H_NAME);
                    ViewData["hotel_names"] = hotel_names;

                    string hotel_name = hotel_names.First().Text;
                    if (newRoom.H_NAME != null)
                    {
                        hotel_name = newRoom.H_NAME;
                    }
                    country_names = getCountryNames(hotel_name);

                    ViewData["country_names"] = country_names;

                    string country_name = country_names.First().Text;

                    foreach (SelectListItem s in country_names)
                    {
                        if (string.Compare(s.Text,newRoom.H_COUNTRY,true) == 0)
                        {
                            country_name = s.Text;
                            break;
                        }
                    }
                    newRoom.H_COUNTRY = country_name;


                    branch_names = getBranchNames(hotel_name, country_name);
                    ViewData["branch_names"] = branch_names;
                    return View(newRoom);
                }
                else                                    //postback due to submit button
                {
                    int error_state = 0;
                    if (string.IsNullOrWhiteSpace(newRoom.ROOMTYPE))
                    {
                        error_state ++;
                        ViewData["ROOMTYPE_ERROR"] = "Room Type is a required field";
                    }
                    if (string.IsNullOrWhiteSpace(newRoom.BEDTYPE))
                    {
                        error_state++;
                        ViewData["BEDTYPE_ERROR"] = "Bed Type is a required field";
                    }
                    if (newRoom.PRICE == null)
                    {
                        error_state++;
                        ViewData["PRICE_ERROR"] = "Price is a required field";
                    }
                    if (newRoom.PRICE == 0)
                    {
                        error_state++;
                        ViewData["PRICE_ERROR"] = "Price cannot be 0!";
                    }
                    string input = Request.Form.Get("PRICE");
                    if (!string.IsNullOrWhiteSpace(input) && newRoom.PRICE == null)
                    {
                        error_state++;
                        ViewData["PRICE_ERROR"] = "Invalid Price! Please enter numerical values only!";
                    }
                    input = Request.Form.Get("NOOFROOM");
                    if (!string.IsNullOrWhiteSpace(input) && (newRoom.NOOFROOM == 0 || newRoom.NOOFROOM == null))
                    {
                        error_state++;
                        ViewData["NOOFROOM_ERROR"] = "Invalid Number of Rooms! Please enter numerical values only!";
                    }
                    if (newRoom.H_NAME != null && newRoom.H_COUNTRY != null && newRoom.H_BRANCHNAME != null && newRoom.ROOMTYPE != null && newRoom.BEDTYPE != null)
                    {
                        var room = from Room in _db.ROOM
                                   where Room.H_NAME == newRoom.H_NAME &&
                                   Room.H_COUNTRY == newRoom.H_COUNTRY &&
                                   Room.H_BRANCHNAME == newRoom.H_BRANCHNAME &&
                                   Room.ROOMTYPE == newRoom.ROOMTYPE &&
                                   Room.BEDTYPE == newRoom.BEDTYPE
                                   select Room;
                        if (room.Count() > 0)
                        {
                            error_state++;
                            ViewData["ERROR"] = "The Hotel already has a room with the same Room Type and Bed Type!";
                        }
                    }
                    error_state += checkLengthAndPopulateError(ViewData, newRoom.DIRECTION, 255, "DIRECTION_ERROR", "Direction");
                    error_state += checkLengthAndPopulateError(ViewData, newRoom.ROOMTYPE, 60, "ROOMTYPE_ERROR", "Room Type");
                    error_state += checkLengthAndPopulateError(ViewData, newRoom.BEDTYPE, 20, "BEDTYPE_ERROR", "Bed Type");
                    error_state += checkLengthAndPopulateError(ViewData, newRoom.DESCRIPTION, 512, "DESCRIPTION_ERROR", "Description");
                    if (error_state > 0)
                    {
                        populateHotelListForDropDownList(ViewData, newRoom.H_NAME, newRoom.H_COUNTRY, newRoom.H_BRANCHNAME);
                        return View(newRoom);
                    }
                    if (file != null && file.ContentLength > 0)
                    {
                        var fileName = Path.GetFileName(file.FileName);
                        filename_with_path = Path.Combine(Server.MapPath("~/Content"), fileName);

                        var directory = Path.GetDirectoryName(filename_with_path);
                        var filename_without_extension = Path.GetFileNameWithoutExtension(filename_with_path);
                        var extension = Path.GetExtension(filename_with_path);

                        int i = 0;
                        while (System.IO.File.Exists(filename_with_path))
                        {
                            i++;
                            fileName = filename_without_extension + i.ToString() + extension;
                            filename_with_path = Path.Combine(directory, fileName);
                        }

                        file.SaveAs(filename_with_path);
                        file_uploaded = true;
                        
                        var relative_path = "/Content/" + fileName;
                        newRoom.ROOMIMAGE = relative_path;
                    }
                    _db.AddToROOM(newRoom);
                    _db.SaveChanges();
                    return RedirectToAction("../AdminMain/ViewDetailsHotel", new { hotelName = newRoom.H_NAME, branchName = newRoom.H_BRANCHNAME, country = newRoom.H_COUNTRY });
                }
            }
            catch (System.Web.HttpException e)
            {
                ViewData["ERROR"] = "An error has occurred during uploading of the image!";
                if (file_uploaded && System.IO.File.Exists(filename_with_path))
                {
                    System.IO.File.Delete(filename_with_path);
                }
                populateHotelListForDropDownList(ViewData, newRoom.H_NAME, newRoom.H_COUNTRY, newRoom.H_BRANCHNAME);
                return View(newRoom);
            }
            catch
            {
                ViewData["ERROR"] = "An unknown error has occurred! Please try again later.";
                if (file_uploaded && System.IO.File.Exists(filename_with_path))
                {
                    System.IO.File.Delete(filename_with_path);
                }
                populateHotelListForDropDownList(ViewData, newRoom.H_NAME, newRoom.H_COUNTRY, newRoom.H_BRANCHNAME);
                return View(newRoom);
            }
        }
        public ActionResult CreateClient()
        {
            return View();
        }
        [HttpPost]
        public ActionResult CreateClient(CLIENT newClient)
        {
            try
            {
                newClient.EMAIL = toTitleCase(newClient.EMAIL);
                newClient.COUNTRY = toTitleCase(newClient.COUNTRY);
                newClient.ADDRESS = toTitleCase(newClient.ADDRESS);
                newClient.PASSPORTNO = toTitleCase(newClient.PASSPORTNO);
                newClient.FIRSTNAME = toTitleCase(newClient.FIRSTNAME);
                newClient.LASTNAME = toTitleCase(newClient.LASTNAME);

                //error checking
                int error_state = 0;
                if (string.IsNullOrWhiteSpace(newClient.EMAIL))
                {
                    error_state++;
                    ViewData["EMAIL_ERROR"] = "Email is a required field";
                }
                if (string.IsNullOrWhiteSpace(newClient.PWD))
                {
                    error_state++;
                    ViewData["PWD_ERROR"] = "Password is a required field";
                }
                if (string.IsNullOrWhiteSpace(newClient.FIRSTNAME))
                {
                    error_state++;
                    ViewData["FIRSTNAME_ERROR"] = "Please enter your first name!";
                }
                if (string.IsNullOrWhiteSpace(newClient.LASTNAME))
                {
                    error_state++;
                    ViewData["LASTNAME_ERROR"] = "Please enter your last name!";
                }
                if (string.IsNullOrWhiteSpace(newClient.PASSPORTNO))
                {
                    error_state++;
                    ViewData["PASSPORTNO_ERROR"] = "NRIC / Passport Number is a required field";
                }
                string input = Request.Form.Get("CONTACT");
                if (string.IsNullOrWhiteSpace(input))
                {
                    error_state++;
                    ViewData["CONTACT_ERROR"] = "Contact is a required field";
                }
                else if (newClient.CONTACT == 0)
                {
                    error_state++;
                    ViewData["CONTACT_ERROR"] = "Invalid Contact!";
                }
                if (string.IsNullOrWhiteSpace(newClient.GENDER))
                {
                    error_state++;
                    ViewData["GENDER_ERROR"] = "Please select your gender!";
                }
                if (string.IsNullOrWhiteSpace(newClient.ADDRESS))
                {
                    error_state++;
                    ViewData["ADDRESS_ERROR"] = "Address is a required field";
                }
                if (string.IsNullOrWhiteSpace(newClient.COUNTRY))
                {
                    error_state++;
                    ViewData["COUNTRY_ERROR"] = "Country is a required field";
                }
                if (newClient.EMAIL != null)
                {
                    var clients = from Client in _db.CLIENT
                                 where Client.EMAIL == newClient.EMAIL
                                 select Client;
                    if (clients.Count() > 0)
                    {
                        error_state++;
                        ViewData["ERROR"] = "A Client with the same Email already exists!";
                    }
                }
                error_state += checkLengthAndPopulateError(ViewData, newClient.EMAIL, 256, "EMAIL_ERROR", "Email");
                error_state += checkLengthAndPopulateError(ViewData, newClient.COUNTRY, 60, "COUNTRY_ERROR", "Country");
                error_state += checkLengthAndPopulateError(ViewData, newClient.FIRSTNAME, 60, "FIRSTNAME_ERROR", "First Name");
                error_state += checkLengthAndPopulateError(ViewData, newClient.LASTNAME, 60, "LASTNAME_ERROR", "Last Name");
                error_state += checkLengthAndPopulateError(ViewData, newClient.PASSPORTNO, 20, "PASSPORTNO_ERROR", "Passport Number");
                error_state += checkLengthAndPopulateError(ViewData, newClient.ADDRESS, 255, "ADDRESS_ERROR", "Address");
                error_state += checkLengthAndPopulateError(ViewData, newClient.PWD, 15, "PWD_ERROR", "Password");
                if (error_state > 0)
                {
                    return View(newClient);
                }

                _db.AddToCLIENT(newClient);
                _db.SaveChanges();
                return RedirectToAction("Index");
            }
            catch
            {
                ViewData["ERROR"] = "An unknown error has occurred! Please try again later.";
                return View(newClient);
            }
        }

        public ActionResult CreateBooking(HOTEL init_hotel = null, ROOM init_room = null)
        {

            BOOKING booking = new BOOKING();
            booking.STARTDATE = System.DateTime.Now.AddDays(1);
            booking.ENDDATE = System.DateTime.Now.AddDays(2);
            populateViewDataForBooking(ViewData, ref booking);

            var id = (from Booking in _db.BOOKING
                     select Booking.BOOKINGID).Max();
            id++;
            booking.BOOKINGID = id;
            booking.NOOFROOM = 1;

            return View(booking);
        }
        [HttpPost]
        public ActionResult CreateBooking(BOOKING newBooking)
        {
            try
            {
                string ctrlname = Request.Params.Get("__EVENTTARGET");
                bool submit = Request.Form.Get("submit1") != null;
                if (!submit)           //postback not due to submit button
                {
                    populateViewDataForBooking(ViewData, ref newBooking);
                    return View(newBooking);
                }
                else                                    //postback due to submit button
                {
                    //error checking
                    int error_state = 0;
                    if (newBooking.NOOFROOM <= 0)
                    {
                        error_state ++;
                        ViewData["NOOFROOM_ERROR"] = "Number of Room must be greater than 0!";
                    }
                    if (newBooking.STARTDATE > newBooking.ENDDATE)
                    {
                        error_state++;
                        ViewData["STARTDATE_ERROR"] = "End date is earlier than start date!";
                    }
                    if (newBooking.STARTDATE < System.DateTime.Now)
                    {
                        error_state++;
                        ViewData["STARTDATE_ERROR"] = "Start date is in the past!";
                    }
                    if (newBooking.ENDDATE < System.DateTime.Now)
                    {
                        error_state++;
                        ViewData["ENDDATE_ERROR"] = "End date is in the past!";
                    }
                    string input = Request.Form.Get("ID");
                    if (input != "0" && newBooking.BOOKINGID == 0)
                    {
                        error_state++;
                        ViewData["BOOKINGID_ERROR"] = "Invalid ID! Please enter numerical values only!";
                    }
                    input = Request.Form.Get("NOOFROOM");
                    if (!string.IsNullOrWhiteSpace(input) && newBooking.NOOFROOM == 0)
                    {
                        error_state++;
                        ViewData["NOOFROOM_ERROR"] = "Invalid Number! Please enter numerical values only!";
                    }
                    var booking = from Booking in _db.BOOKING
                                where Booking.BOOKINGID == newBooking.BOOKINGID
                                select Booking;
                    if (booking.Count() > 0)
                    {
                        error_state++;
                        var max = (from Booking in _db.BOOKING
                                   select Booking.BOOKINGID).Max();
                        max++;
                        ViewData["ERROR"] = "Booking with the ID already exists! Please choose a different ID! (Suggested ID: " + max.ToString() + ")";
                    }
                    error_state += checkLengthAndPopulateError(ViewData, newBooking.H_COUNTRY, 256, "EMAIL_ERROR", "Email");
                    if (error_state > 0)
                    {
                        populateViewDataForBooking(ViewData, ref newBooking);
                        return View(newBooking);
                    }

                    var price = from Room in _db.ROOM
                                where Room.H_NAME == newBooking.H_NAME &&
                                Room.H_COUNTRY == newBooking.H_COUNTRY &&
                                Room.H_BRANCHNAME == newBooking.H_BRANCHNAME &&
                                Room.ROOMTYPE == newBooking.R_ROOMTYPE &&
                                Room.BEDTYPE == newBooking.R_BEDTYPE
                                select Room.PRICE;
                    newBooking.PRICEPERROOM = price.First();

                    _db.AddToBOOKING(newBooking);
                    _db.SaveChanges();
                    return RedirectToAction("index");
                }
            }
            catch
            {
                ViewData["ERROR"] = "An unknown error has occurred! Please try again later.";
                populateViewDataForBooking(ViewData, ref newBooking);
                return View(newBooking);
            }
        }
        private void populateHotelListForDropDownList(ViewDataDictionary ViewData, string hotel_name, string country_name, string branch_name)
        {
            var hotel_names = getHotelNames(hotel_name);
            var country_names = getCountryNames(hotel_name, country_name);
            var branch_names = getBranchNames(hotel_name, country_name, branch_name);
            ViewData["hotel_names"] = hotel_names;
            ViewData["country_names"] = country_names;
            ViewData["branch_names"] = branch_names;
        }
        private void populateRoomListForDropDownList(ViewDataDictionary ViewData,string hotel_name, string country_name, string branch_name, string room_type, string bed_type)
        {
            var room_types = getRoomTypes(hotel_name, country_name, branch_name, room_type);
            var bed_types = getBedTypes(hotel_name, country_name, branch_name, room_type, bed_type);
        }
        private SelectList getHotelNames(string selected = null)
        {
            var hotel_names = new SelectList((from Hotel in _db.HOTEL
                                              select new SelectListItem
                                              {
                                                  Text = Hotel.HOTEL_NAME,
                                                  Value = Hotel.HOTEL_NAME
                                              }).Distinct(), "Value", "Text", selected);
            return hotel_names;
        }
        private SelectList getCountryNames(string hotel_name, string selected = null)
        {
            var country_names = new SelectList((from Hotel in _db.HOTEL
                                                where (Hotel.HOTEL_NAME == hotel_name)
                                                select new SelectListItem
                                                {
                                                    Text = Hotel.COUNTRY,
                                                    Value = Hotel.COUNTRY
                                                }).Distinct(), "Value", "Text", selected);
            return country_names;
        }
        private SelectList getBranchNames(string hotel_name, string country_name, string selected = null)
        {
            var branch_names = new SelectList((from Hotel in _db.HOTEL
                                               where Hotel.HOTEL_NAME == hotel_name &&
                                               Hotel.COUNTRY == country_name
                                               select new SelectListItem
                                               {
                                                   Text = Hotel.BRANCHNAME,
                                                   Value = Hotel.BRANCHNAME
                                               }).Distinct(), "Value", "Text", selected);
            return branch_names;
        }
        private SelectList getHotelWithRoomNames(string selected = null)
        {
            var hotel_names = new SelectList((from Room in _db.ROOM
                                              select new SelectListItem
                                              {
                                                  Text = Room.H_NAME,
                                                  Value = Room.H_NAME
                                              }).Distinct(), "Value", "Text", selected);
            return hotel_names;
        }
        private SelectList getCountryWithRoomNames(string hotel_name, string selected = null)
        {
            var country_names = new SelectList((from Hotel in _db.HOTEL
                                                where (Hotel.HOTEL_NAME == hotel_name)
                                                select new SelectListItem
                                                {
                                                    Text = Hotel.COUNTRY,
                                                    Value = Hotel.COUNTRY
                                                }).Distinct(), "Value", "Text", selected);
            return country_names;
        }
        private SelectList getBranchWithRoomNames(string hotel_name, string country_name, string selected = null)
        {
            var branch_names = new SelectList((from Hotel in _db.HOTEL
                                               where Hotel.HOTEL_NAME == hotel_name &&
                                               Hotel.COUNTRY == country_name
                                               select new SelectListItem
                                               {
                                                   Text = Hotel.BRANCHNAME,
                                                   Value = Hotel.BRANCHNAME
                                               }).Distinct(), "Value", "Text", selected);
            return branch_names;
        }
        private SelectList getRoomTypes(string hotel_name, string country_name, string branch_name, string selected = null)
        {
            var room_types = new SelectList((from Room in _db.ROOM
                                               where Room.H_NAME == hotel_name &&
                                               Room.H_COUNTRY == country_name &&
                                               Room.H_BRANCHNAME == branch_name
                                               select new SelectListItem
                                               {
                                                   Text = Room.ROOMTYPE,
                                                   Value = Room.ROOMTYPE
                                               }).Distinct(), "Value", "Text", selected);
            return room_types;
        }
        private SelectList getBedTypes(string hotel_name, string country_name, string branch_name, string room_type, string selected = null)
        {
            var bed_types = new SelectList((from Room in _db.ROOM
                                             where Room.H_NAME == hotel_name &&
                                             Room.H_COUNTRY == country_name &&
                                             Room.H_BRANCHNAME == branch_name &&
                                             Room.ROOMTYPE == room_type
                                             select new SelectListItem
                                             {
                                                 Text = Room.BEDTYPE,
                                                 Value = Room.BEDTYPE
                                             }).Distinct(), "Value", "Text", selected);
            return bed_types;
        }
        private SelectList getClientEmails(string selected = null)
        {
            var client_lists = new SelectList((from Client in _db.CLIENT
                                               select new SelectListItem
                                               {
                                                   Text = Client.EMAIL,
                                                   Value = Client.EMAIL
                                               }), "Value", "Text", selected);
            return client_lists;
        }
        private void populateViewDataForBooking(ViewDataDictionary ViewData, ref BOOKING booking)
        {
            //get client emails
            var client_emails = getClientEmails();
            ViewData["client_emails"] = client_emails;

            //get hotel list
            var hotel_names = new SelectList((from Room in _db.ROOM
                                              select new SelectListItem
                                              {
                                                  Text = Room.H_NAME,
                                                  Value = Room.H_NAME
                                              }).Distinct(), "Value", "Text");
            ViewData["hotel_names"] = hotel_names;

            //get country list
            string hotel_name = hotel_names.First().Text;
            if (booking.H_NAME != null)
            {
                foreach (SelectListItem i in hotel_names)
                {
                    if (string.Compare(i.Text, booking.H_NAME, true) == 0)
                    {
                        hotel_name = i.Text;
                        break;
                    }
                }
            }
            booking.H_NAME = hotel_name;
            var same_hotel_list = from Room in _db.ROOM
                                  where Room.H_NAME == hotel_name
                                  select Room;
            var country_names = new SelectList((from Room in same_hotel_list
                                                select new SelectListItem
                                                {
                                                    Text = Room.H_COUNTRY,
                                                    Value = Room.H_COUNTRY
                                                }).Distinct(), "Value", "Text");
            ViewData["country_names"] = country_names;

            //get branch list
            string country_name = country_names.First().Text;
            if (booking.H_COUNTRY != null)
            {
                foreach (SelectListItem i in country_names)
                {
                    if (string.Compare(i.Text, booking.H_COUNTRY, true) == 0)
                    {
                        country_name = i.Text;
                        break;
                    }
                }
            }
            booking.H_COUNTRY = country_name;
            var same_country_list = from Room in same_hotel_list
                                    where Room.H_COUNTRY == country_name
                                    select Room;
            var branch_names = new SelectList((from Room in same_country_list
                                               select new SelectListItem
                                               {
                                                   Text = Room.H_BRANCHNAME,
                                                   Value = Room.H_BRANCHNAME,
                                               }).Distinct(), "Value", "Text");
            ViewData["branch_names"] = branch_names;

            //get room type list
            string branch_name = branch_names.First().Text;
            if (booking.H_BRANCHNAME != null)
            {
                foreach (SelectListItem i in branch_names)
                {
                    if (string.Compare(i.Text, booking.H_BRANCHNAME, true) == 0)
                    {
                        branch_name = i.Text;
                        break;
                    }
                }
            }
            booking.H_BRANCHNAME = branch_name;
            var same_branch_list = from Room in same_country_list
                                   where Room.H_BRANCHNAME == branch_name
                                   select Room;
            var room_types = new SelectList((from Room in same_branch_list
                                             select new SelectListItem
                                             {
                                                 Text = Room.ROOMTYPE,
                                                 Value = Room.ROOMTYPE,
                                             }).Distinct(), "Value", "Text");
            ViewData["room_types"] = room_types;

            string room_type = room_types.First().Text;
            if (booking.R_ROOMTYPE != null)
            {
                foreach (SelectListItem i in room_types)
                {
                    if (string.Compare(i.Text, booking.R_ROOMTYPE, true) == 0)
                    {
                        room_type = i.Text;
                        break;
                    }
                }
            }
            booking.R_ROOMTYPE = room_type;
            var same_room_list = from Room in same_branch_list
                                 where Room.ROOMTYPE == room_type
                                 select Room;
            var bed_types = new SelectList((from Room in same_room_list
                                            select new SelectListItem
                                            {
                                                Text = Room.BEDTYPE,
                                                Value = Room.BEDTYPE,
                                            }).Distinct(), "Value", "Text");
            ViewData["bed_types"] = bed_types;

            string bed_type = bed_types.First().Text;
            if (booking.R_BEDTYPE != null)
            {
                foreach (SelectListItem i in bed_types)
                {
                    if (string.Compare(i.Text, booking.R_BEDTYPE, true) == 0)
                    {
                        bed_type = i.Text;
                        break;
                    }
                }
            }
            booking.R_BEDTYPE = bed_type;

            var price = from Room in _db.ROOM
                        where Room.H_NAME == hotel_name &&
                        Room.H_COUNTRY == country_name &&
                        Room.H_BRANCHNAME == branch_name &&
                        Room.ROOMTYPE == room_type &&
                        Room.BEDTYPE == bed_type
                        select Room.PRICE;
            booking.PRICEPERROOM = price.First();
        }
        private int checkLengthAndPopulateError(ViewDataDictionary ViewData, string str, int length, string error_field, string error_string)
        {
            int error_state = 0;
            if (str != null && str.Length > length)
            {
                error_state++;
                ViewData[error_field] = error_string +" is too long! Maximium " + length.ToString() + " characters!";
            }
            return error_state;
        }
        private string toTitleCase(string str)
        {
            if (str != null)
            {
                System.Globalization.TextInfo txtInfo = new System.Globalization.CultureInfo("en-US", false).TextInfo;
                str = txtInfo.ToTitleCase(str);
                str = str.Trim();
            }
            return str;
        }
    }
}
